package cn.itedus.lottery.domain.strategy.service.algorithm.impl;

/**
 * @author aodre , QQ : 480029069
 * @date 2023/10/5 14:54
 */

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


/*
 二分均值法 + （redis）预分配 是大多数的场景， 并不是微信的
 这里可以拓展到 相应 涉及到 金额相关的 抽奖算法， 可以借鉴一下下面的做法
  蓄水池算法 +   （ 二分均值法 +  预分配）   ，感觉很完美
 */
public class RedPacket {



    /*
      金额版本
     */
    public static List<BigDecimal> divideRedPacket(BigDecimal totalAmount, int totalPeople) {
        List<BigDecimal> amountList = new ArrayList<>();
        BigDecimal restAmount = totalAmount;
        int restPeople = totalPeople;

        Random random = new Random();
        for (int i = 0; i < totalPeople - 1; i++) {
            // 生成随机数，范围在0.01 ~ (剩余金额/剩余人数) * 2
            BigDecimal amount = restAmount.multiply(new BigDecimal(2))
                    .divide(new BigDecimal(restPeople), 2, BigDecimal.ROUND_DOWN);
            amount = amount.multiply(new BigDecimal(random.nextDouble())).setScale(2, BigDecimal.ROUND_DOWN);
            amountList.add(amount);
            restAmount = restAmount.subtract(amount);
            restPeople--;
        }

        amountList.add(restAmount); // 最后一个红包直接使用剩余金额
        return amountList;
    }


    /*
      抖音福袋 抖币 ,整数类型
      [1,  剩余金额 / 剩余人数 * 2)
     */


    public static List<Integer> divideRedPacket(int totalAmount,int totalPeople){
        List<Integer> ans = new ArrayList<>();
        Random random = new Random();
        int rest = totalAmount , restP = totalPeople;
        for (int i = 0; i < totalPeople - 1; i++) {
            int r = rest / restP * 2 - 1;  // [0, r - 1)
            int sub = random.nextInt(r) + 1; // [1, r)
            ans.add(sub);
            rest -= sub;
            restP--;
        }
        int last = rest;
        ans.add(last);
        return ans;
    }

    public static void main1(String[] args) {
        BigDecimal totalAmount = new BigDecimal("50.00"); // 总金额
        int totalPeople = 100; // 总人数

        List<BigDecimal> amountList = divideRedPacket(totalAmount, totalPeople);
        BigDecimal sum = new BigDecimal(0);
        for (BigDecimal amount : amountList) {
            System.out.println("抢到红包金额：" + amount);
            sum = sum.add(amount);
        }
        System.out.println(sum);
    }
    public static void main(String[] args) {
        int totalAmount = 2000;
        int totalPeople = 200;

        List<Integer> result = divideRedPacket(totalAmount, totalPeople);
        result.forEach(System.out::println);
    }
}